#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#define MAXLINE 1024
#define TRUE 1
#define FLAG "END\n"      // 结束标志
#define USERNAME "Client" // client名称

// 打印当前时间
void printCurrentTime()
{
    time_t t0 = time(NULL);
    fputs(ctime(&t0), stdout);
}

int main(int argc, char **argv)
{
    int socket_fd, signal;
    char recv_message[MAXLINE + 1], send_message[MAXLINE + 1]; // 接受数据buffer和发送数据buffer
    struct sockaddr_in6 servaddr;
    // 打印开始信息
    printf("#########################\n");
    printCurrentTime();
    printf("Start Connect\n");
    printf("This is client %s \n", USERNAME);
    printf("#########################\n");

    if (argc != 2)
    {
        perror("usage: a.out <IPaddress>");
    }

    if ((socket_fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) // 创建套接字
    {
        perror("failed to create socket!");
    }

    // 初始化服务器地址
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin6_family = AF_INET6;
    servaddr.sin6_port = htons(20000);

    // 将数值地址转换成二进制形式，存入servaddr.sin6_addr
    if (inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr) <= 0)
    {
        perror("failed to call inet_pton function!");
    }

    // 连接server
    if (connect(socket_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("failed to connect!");
    }

    char user_prefix[100] = {}; // 聊天前缀
    char tmp_send[MAXLINE + 100] = {};
    strcpy(user_prefix, USERNAME);
    strcat(user_prefix, ": "); // 组成前缀

    // 创建子进程
    pid_t pid;
    pid = fork();
    if (pid < 0)
    {
        perror("failed to fork!");
    }

    if (pid == 0)
    {
        while (TRUE) // 用于接受server数据
        {
            memset(recv_message, 0, sizeof(recv_message)); // 清空接受消息buffer
            signal = read(socket_fd, recv_message, sizeof(recv_message)); // 接受server发来数据
            if (signal == 0)
            {

                printf("server is close!\n");
                break;
            }
            else if (signal == -1)
            {
                perror("failed to read!");
            }
            if (strcmp(recv_message, FLAG) == 0) // server发送结束信号
            {
                printf("receive close flag from server\n");
                break;
            }
            recv_message[signal] = 0;
            if (fputs(recv_message, stdout) == EOF)
            {
                perror("failed to fputs!");
            }
        }
        close(socket_fd);
        kill(getppid(), SIGUSR1);
        // 打印结束信息
        printf("#########################\n");
        printf("Connection Close By Server\n");
        printf("Close Time:\n");
        printCurrentTime();
        printf("#########################\n");
        exit(EXIT_SUCCESS);
    }
    else
    {   // 用于发送数据到server
        while (fgets(send_message, MAXLINE, stdin) != NULL)
        {
            if (strcmp(send_message, FLAG) == 0) // 将buffer数据发送给server
            {
                signal = send(socket_fd, send_message, strlen(send_message), 0);
            }
            else
            {
                strcat(tmp_send, user_prefix); //添加前缀
                strcat(tmp_send, send_message);
                signal = send(socket_fd, tmp_send, strlen(tmp_send), 0);
            }
            if (signal < 0)
            {
                perror("failed to send!");
            }
            // 清空buffer
            memset(send_message, 0, strlen(send_message));
            memset(tmp_send, 0, strlen(tmp_send));
        }
        close(socket_fd);
    }
    // 打印结束信息
    printf("#########################\n");
    printf("Connection Close\n");
    printf("Close Time:\n");
    printCurrentTime();
    printf("#########################\n");
    exit(0);
}